package org.tjc.net.manager.config.json;

import lombok.Data;
import org.tjc.net.manager.bean.HttpRequest;
import org.tjc.net.manager.exception.ParseConfException;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: tjc
 * @description
 * @Date Created in 18:10 2020-12-12
 */
@Data
public class NgLocationModule extends NgModule {
    private String path;
    private String proxy_pass;


    public static ModuleSet ngSet = (ctx, conf) -> {

        List<Object> serverConfs = conf.getList("");
        List<Configuration> locationConfList = serverConfs.stream().map(Configuration::from).collect(Collectors.toList());
        for (Configuration locationConf : locationConfList) {
            NgLocationModule locationModule = new NgLocationModule();
            locationModule.setCtx(ctx);

            for (String key : locationConf.getKeys()) {
                if (!MetaNgCommand.contains(key)) {
                    throw new ParseConfException("unexpect key: " + key);
                }
                MetaNgCommand subCmd = MetaNgCommand.get(key);
                if (subCmd.getType() == MetaNgCommand.CMD_MODULE) {
                    Configuration subConf = locationConf.getConfiguration(key);
                    subCmd.invoke(locationModule, subConf);
                } else if (subCmd.getType() == MetaNgCommand.CMD_LINE) {
                    Object value = locationConf.get(key);
                    subCmd.invoke(locationModule,key, value);
                }

            }
            ((NgServerModule) ctx).addLocation(locationModule);

        }
    };

    public HttpRequest decorate(HttpRequest request) {
        request.setHeader("Host", proxy_pass);
        return request;
    }

    @Override
    public void init() {
        Map<String, NgCommand> cmdMap = getCommands().stream().collect(Collectors.toMap(NgCommand::getName, ngCommand -> ngCommand));

        NgCommand cmd = null;

        if ((cmd = cmdMap.get("path")) != null) {
            this.path = (String) cmd.getValues().get(0);
        } else {
            this.path = "/";
        }
    }
}
